import { reactive } from 'vue'

// 缓存类型定义
export interface CacheEntry<T = any> {
  data: T
  timestamp: number
  size: number
  accessCount: number
  lastAccess: number
}

export interface CacheConfig {
  maxMemorySize: number // 最大内存使用量（字节）
  maxEntries: number // 最大缓存条目数
  ttl: number // 缓存生存时间（毫秒）
  enablePersistence: boolean // 是否启用持久化
}

// 默认配置
const DEFAULT_CONFIG: CacheConfig = {
  maxMemorySize: 512 * 1024 * 1024, // 512MB
  maxEntries: 1000,
  ttl: 30 * 60 * 1000, // 30分钟
  enablePersistence: true
}

// 缓存统计信息
export interface CacheStats {
  totalSize: number
  entryCount: number
  hitRate: number
  memoryUsage: string
}

/**
 * 高性能多层缓存管理器
 * 支持内存缓存、LRU淘汰、持久化存储
 */
export class CacheManager {
  private cache = new Map<string, CacheEntry>()
  private config: CacheConfig
  private stats = reactive({
    hits: 0,
    misses: 0,
    totalSize: 0
  })

  constructor(config: Partial<CacheConfig> = {}) {
    this.config = { ...DEFAULT_CONFIG, ...config }
    this.initializeFromPersistence()
  }

  /**
   * 设置缓存项
   */
  set<T>(key: string, data: T, options?: { ttl?: number; persist?: boolean }): void {
    const size = this.calculateSize(data)
    const entry: CacheEntry<T> = {
      data,
      timestamp: Date.now(),
      size,
      accessCount: 0,
      lastAccess: Date.now()
    }

    // 检查是否需要清理空间
    this.ensureSpace(size)

    this.cache.set(key, entry)
    this.stats.totalSize += size

    // 持久化存储（异步）
    if (options?.persist !== false && this.config.enablePersistence) {
      this.persistEntry(key, entry)
    }

    console.log(`[Cache] 缓存已设置: ${key}, 大小: ${(size / 1024 / 1024).toFixed(2)}MB`)
  }

  /**
   * 获取缓存项
   */
  get<T>(key: string): T | null {
    const entry = this.cache.get(key)
    
    if (!entry) {
      this.stats.misses++
      return null
    }

    // 检查是否过期
    if (this.isExpired(entry)) {
      this.delete(key)
      this.stats.misses++
      return null
    }

    // 更新访问统计
    entry.accessCount++
    entry.lastAccess = Date.now()
    this.stats.hits++

    return entry.data as T
  }

  /**
   * 检查缓存是否存在
   */
  has(key: string): boolean {
    const entry = this.cache.get(key)
    return entry !== undefined && !this.isExpired(entry)
  }

  /**
   * 删除缓存项
   */
  delete(key: string): boolean {
    const entry = this.cache.get(key)
    if (entry) {
      this.stats.totalSize -= entry.size
      this.cache.delete(key)
      this.removePersistentEntry(key)
      return true
    }
    return false
  }

  /**
   * 清空所有缓存
   */
  clear(): void {
    this.cache.clear()
    this.stats.totalSize = 0
    this.stats.hits = 0
    this.stats.misses = 0
    this.clearPersistentStorage()
    console.log('[Cache] 所有缓存已清空')
  }

  /**
   * 获取缓存统计信息
   */
  getStats(): CacheStats {
    const totalRequests = this.stats.hits + this.stats.misses
    return {
      totalSize: this.stats.totalSize,
      entryCount: this.cache.size,
      hitRate: totalRequests > 0 ? (this.stats.hits / totalRequests) * 100 : 0,
      memoryUsage: (this.stats.totalSize / 1024 / 1024).toFixed(2) + 'MB'
    }
  }

  /**
   * 预热缓存 - 批量加载数据
   */
  async warmup(dataLoader: () => Promise<Record<string, any>>): Promise<void> {
    try {
      console.log('[Cache] 开始缓存预热...')
      const data = await dataLoader()
      
      for (const [key, value] of Object.entries(data)) {
        this.set(key, value, { persist: true })
      }
      
      console.log(`[Cache] 缓存预热完成，加载了 ${Object.keys(data).length} 个条目`)
    } catch (error) {
      console.error('[Cache] 缓存预热失败:', error)
    }
  }

  /**
   * 确保有足够空间存储新数据
   */
  private ensureSpace(requiredSize: number): void {
    // 检查内存限制
    while (this.stats.totalSize + requiredSize > this.config.maxMemorySize || 
           this.cache.size >= this.config.maxEntries) {
      this.evictLRU()
    }
  }

  /**
   * LRU淘汰策略
   */
  private evictLRU(): void {
    let oldestKey = ''
    let oldestTime = Date.now()

    for (const [key, entry] of this.cache.entries()) {
      if (entry.lastAccess < oldestTime) {
        oldestTime = entry.lastAccess
        oldestKey = key
      }
    }

    if (oldestKey) {
      console.log(`[Cache] LRU淘汰: ${oldestKey}`)
      this.delete(oldestKey)
    }
  }

  /**
   * 检查缓存项是否过期
   */
  private isExpired(entry: CacheEntry): boolean {
    return Date.now() - entry.timestamp > this.config.ttl
  }

  /**
   * 计算数据大小（粗略估算）
   */
  private calculateSize(data: any): number {
    if (typeof data === 'string') {
      return data.length * 2 // UTF-16编码
    }
    if (typeof data === 'object') {
      return JSON.stringify(data).length * 2
    }
    return 64 // 基础对象大小
  }

  /**
   * 持久化缓存项到IndexedDB
   */
  private async persistEntry(key: string, entry: CacheEntry): Promise<void> {
    try {
      const db = await this.openCacheDB()
      const transaction = db.transaction(['cache'], 'readwrite')
      const store = transaction.objectStore('cache')
      
      await new Promise<void>((resolve, reject) => {
        const request = store.put({ key, ...entry })
        request.onsuccess = () => resolve()
        request.onerror = () => reject(request.error)
      })
      
      db.close()
    } catch (error) {
      console.warn('[Cache] 持久化失败:', error)
    }
  }

  /**
   * 从持久化存储初始化缓存
   */
  private async initializeFromPersistence(): Promise<void> {
    if (!this.config.enablePersistence) return

    try {
      const db = await this.openCacheDB()
      const transaction = db.transaction(['cache'], 'readonly')
      const store = transaction.objectStore('cache')
      
      const entries = await new Promise<any[]>((resolve, reject) => {
        const request = store.getAll()
        request.onsuccess = () => resolve(request.result)
        request.onerror = () => reject(request.error)
      })
      
      let loadedCount = 0
      for (const item of entries) {
        const { key, ...entry } = item
        if (!this.isExpired(entry)) {
          this.cache.set(key, entry)
          this.stats.totalSize += entry.size
          loadedCount++
        }
      }
      
      db.close()
      console.log(`[Cache] 从持久化存储恢复了 ${loadedCount} 个缓存条目`)
    } catch (error) {
      console.warn('[Cache] 从持久化存储恢复失败:', error)
    }
  }

  /**
   * 删除持久化缓存项
   */
  private async removePersistentEntry(key: string): Promise<void> {
    try {
      const db = await this.openCacheDB()
      const transaction = db.transaction(['cache'], 'readwrite')
      const store = transaction.objectStore('cache')
      
      await new Promise<void>((resolve, reject) => {
        const request = store.delete(key)
        request.onsuccess = () => resolve()
        request.onerror = () => reject(request.error)
      })
      
      db.close()
    } catch (error) {
      console.warn('[Cache] 删除持久化缓存项失败:', error)
    }
  }

  /**
   * 清空持久化存储
   */
  private async clearPersistentStorage(): Promise<void> {
    try {
      const db = await this.openCacheDB()
      const transaction = db.transaction(['cache'], 'readwrite')
      const store = transaction.objectStore('cache')
      
      await new Promise<void>((resolve, reject) => {
        const request = store.clear()
        request.onsuccess = () => resolve()
        request.onerror = () => reject(request.error)
      })
      
      db.close()
    } catch (error) {
      console.warn('[Cache] 清空持久化存储失败:', error)
    }
  }

  /**
   * 打开缓存数据库
   */
  private openCacheDB(): Promise<IDBDatabase> {
    return new Promise((resolve, reject) => {
      const request = indexedDB.open('LogVisionCache', 1)
      
      request.onerror = () => reject(request.error)
      request.onsuccess = () => resolve(request.result)
      
      request.onupgradeneeded = (event) => {
        const db = (event.target as IDBOpenDBRequest).result
        if (!db.objectStoreNames.contains('cache')) {
          db.createObjectStore('cache', { keyPath: 'key' })
        }
      }
    })
  }
}

// 全局缓存管理器实例
export const globalCacheManager = new CacheManager()

// 专用缓存管理器
export const logDataCache = new CacheManager({
  maxMemorySize: 256 * 1024 * 1024, // 256MB
  maxEntries: 500,
  ttl: 60 * 60 * 1000 // 1小时
})

export const dumpPathCache = new CacheManager({
  maxMemorySize: 16 * 1024 * 1024, // 16MB
  maxEntries: 100,
  ttl: 24 * 60 * 60 * 1000 // 24小时
})

export const componentCache = new CacheManager({
  maxMemorySize: 64 * 1024 * 1024, // 64MB
  maxEntries: 200,
  ttl: 30 * 60 * 1000 // 30分钟
})